package com.aoxin.service.impl.attendance;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import com.aoxin.mapper.attend.ClassRecordMapper;
import com.aoxin.model.SlfUserCourseCondition;
import com.aoxin.model.attend.ClassRecord;
import com.aoxin.model.attend.QueryRecord;
import com.aoxin.util.cardException.CardException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.aoxin.mapper.attendance.SlfAttendanceMapper;
import com.aoxin.mapper.course.systemCourse.SchoolCourseDao;
import com.aoxin.mapper.course.systemCourse.SlfOrderCourseMapper;
import com.aoxin.mapper.course.systemCourse.SlfSyllabusMapper;
import com.aoxin.mapper.course.webCourse.MyCourseMapper;
import com.aoxin.mapper.course.webCourse.SlfChildrenMapper;
import com.aoxin.model.attendance.SlfAttendance;
import com.aoxin.model.attendance.SlfClassRecord;
import com.aoxin.model.course.SchoolCourse;
import com.aoxin.model.course.SlfChildren;
import com.aoxin.model.course.SlfSyllabus;
import com.aoxin.service.inter.attendance.AttendanceService;
import com.aoxin.service.inter.attendance.ClassRecordService;
import com.aoxin.util.AESUtil;
import com.aoxin.util.ErrorUtil;
import com.aoxin.util.enumerate.AttendanceType;

@Service("attendanceService")
public class AttendanceServiceImpl implements AttendanceService {

    Logger logger = LoggerFactory.getLogger(AttendanceServiceImpl.class);
    @Autowired
    private ClassRecordMapper classRecordMapper;
    @Autowired
    private SlfChildrenMapper slfChildrenMapper;


    /**
     * 孩子打卡
     * @param aseChildrenId
     * @throws Exception
     */
    @Override
    @Transactional
    public void insertAttendance(String aseChildrenId) throws Exception {
        Assert.notNull(aseChildrenId, String.format(ErrorUtil.PARAMETER_NULL, "attendance"));
        // 解密孩子ID
        /* aseChildrenId = aseChildrenId.replaceAll("$aoxin", "+");*/
        Integer childrenId = Integer.parseInt(AESUtil.decrypt(aseChildrenId, AESUtil.PASSWORD));
        //查询最近三个小时内的B类C类且没有打过卡的课程
        List<SlfUserCourseCondition> orderCourseList = this.classRecordMapper.getOrderCourseBC(childrenId, 0);
        // 获取孩子信息
        SlfChildren children = this.slfChildrenMapper.getAChildren(childrenId);
        if (null == children) {
            throw new IllegalArgumentException(ErrorUtil.CHILDREN_NULL);
        }
        // 判断课程是否能够进行打卡
        if (orderCourseList != null && orderCourseList.size() != 0) {
            logger.info("孩子打卡");
            //判断最近一条课程考勤状态,返回考勤状态
            Date now = stringToDate(orderCourseList.get(0).getNow());
            Date startTime = stringToDate(orderCourseList.get(0).getStartTime());
            Date endTime = stringToDate(orderCourseList.get(0).getEmployTime());
            Integer type = checkDate(now, startTime, endTime);

            //下标
            int index = 0;
            for (SlfUserCourseCondition orderCourse : orderCourseList) {
                //课程类型
                int courseType = orderCourse.getCourseType().intValue();
                //课程id
                long syllabusId = orderCourse.getId();
                Integer kol = -1;
                //最近课程打卡状态会根据时间决定
                if (index == 0) {
                    kol = this.classRecordMapper.addRecord(createClassRecord(children, orderCourse, now, type));
                } else {
                    //第一堂课打了卡后面就算作打卡
                    now = stringToDate(orderCourse.getNow());
                    kol = this.classRecordMapper.addRecord(createClassRecord(children, orderCourse, now, 0));
                    //修改打卡状态为已打卡
                }
                //修改打卡状态为已打卡
                if (kol > 0) {
                    Integer col = -1;
                    if (courseType == 1) {
                        //B类
                        col = this.classRecordMapper.updateCardStatusB(syllabusId);
                    } else if (courseType == 2) {
                        //C类
                        col = this.classRecordMapper.updateCardStatusC(syllabusId);
                    } else {
                        System.out.println("课堂类型错误");
                        throw new CardException(ErrorUtil.CARD_TYPE);
                    }
                    if (col <= 0) {
                        logger.info("打卡状态修改失败");
                        throw new CardException(ErrorUtil.CARD_UPDATE);
                    } else {
                        logger.info("打卡成功");
                    }
                } else {
                    logger.info("插入考勤失败");
                    throw new CardException(ErrorUtil.CARD_ADD);
                }
                index++;
            }
        } else {
            logger.info("孩子打卡轨迹");
            //查询最近三个小时内的B类C类且已经打过卡的课程
            List<SlfUserCourseCondition> orderNoCourseList = this.classRecordMapper.getOrderCourseBC(childrenId, 1);
           if(orderNoCourseList!=null&&orderNoCourseList.size()!=0){
               for (SlfUserCourseCondition orderCourse : orderNoCourseList) {
                   //考勤id
                   Date now = stringToDate(orderCourse.getNow());
                   long syllabusId = orderCourse.getId();
                   int courseType = orderCourse.getCourseType();
                   //验证是否考勤表有打卡数据
                   Integer countCard = this.classRecordMapper.checkRecord(syllabusId,courseType);
                   if (countCard > 0) {
                       Integer kol=-1;
                       //考勤表中有打卡数据(表明此行为再次打卡),记录到用户考勤轨迹表中
                       kol = this.classRecordMapper.addUserRecord(createClassRecord(children, orderCourse, now,null));
                       if(kol>0){
                           logger.info("孩子打卡轨迹插入成功");
                       }else{
                           throw new CardException(ErrorUtil.CARD_ADD_USER);
                       }
                   }else{
                       throw new CardException(ErrorUtil.CARD_DATA_DISUNITY);
                   }
               }
           }else{
               throw new CardException(ErrorUtil.CARD_ORDER);
           }

        }

    }

    /**
     * 查询考勤记录
     * @param queryRecord
     * @return
     */
    @Override
    public List<QueryRecord> getRecord(QueryRecord queryRecord) {
        List<QueryRecord> record = classRecordMapper.getRecord(queryRecord);
        if(record!=null&&record.size()!=0){
            return record;
        }else{
            throw new CardException(ErrorUtil.CARD_QUERY_FALUED);
        }
    }


    /**
     * 判断考勤类型
     * @param attendanceDate 规定时间
     * @param newDate        现在的时间
     * @return true/false
     */
    private boolean getAttendanceType(Date attendanceDate, Date newDate) {
        if (null != attendanceDate && null != newDate) {
            if (attendanceDate.getTime() >= newDate.getTime()) {
                return true;
            } else {
                return false;
            }
        }
        return true;
    }

    /**
     * 字符串转date类型
     * @param str
     * @return
     */
    private Date stringToDate(String str) {
        Date date = null;
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            date = dateFormat.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 获取某分钟后的某个时间
     * @param date
     * @param minute
     * @return
     */
    private Date addOrReduceDate(Date date, Integer minute, String symbol) {
        long currentTime = date.getTime();
        if (symbol.equalsIgnoreCase("+")) {
            currentTime += minute * 60 * 1000;
        } else if (symbol.equalsIgnoreCase("-")) {
            currentTime -= minute * 60 * 1000;
        } else {
            System.out.println("未判断的符号");
        }
        Date nowDate = new Date(currentTime);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(dateFormat.format(nowDate));
        return nowDate;
    }

    /**
     * 通过现在时间比较
     *
     * @param nowDate
     * @param startDate
     * @return
     * @throws Exception
     */
    private Integer checkDate(Date nowDate, Date startDate, Date endDate) throws Exception {
        if (nowDate.getTime() <= startDate.getTime()) {
            //打卡时间在课程开始前3小时内,记作准时
            return 0;
        } else if (nowDate.getTime() > startDate.getTime() && nowDate.getTime() < endDate.getTime()) {
            //迟到
            return 1;
        } else {
            System.out.println("考勤未知判断");
            throw new CardException(ErrorUtil.CARD_ERROR);
        }
    }

    /**
     * 日期转字符串
     *
     * @param date
     * @return
     * @throws ParseException
     */
    public String dateToString(Date date) throws ParseException {
        return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(date);
    }

    /**
     * 插入数据封装
     *
     * @param children
     * @param orderCourse
     * @param nowDate
     * @param type
     * @return
     * @throws ParseException
     */
    private ClassRecord createClassRecord(SlfChildren children, SlfUserCourseCondition orderCourse, Date nowDate, Integer type) throws ParseException {
        // 设置孩子、用户信息
        ClassRecord classRecord = new ClassRecord();
        classRecord.setSchoolId(String.valueOf(children.getSchoolId()));
        classRecord.setSchoolName(children.getSchoolName());
        classRecord.setUserId(children.getUserId());
        classRecord.setUserName(children.getUserName());
        classRecord.setChildrenId(children.getChildrenId());
        classRecord.setChildrenName(children.getName());
        //设置考勤基本信息
        classRecord.setCourseType(orderCourse.getCourseType());
        classRecord.setClassroomId(orderCourse.getClassroomId());
        classRecord.setClassroomName(orderCourse.getClassroomName());
        classRecord.setCourseId(orderCourse.getCourseId());
        classRecord.setCourseName(orderCourse.getCourse());
        classRecord.setSyllabusId(orderCourse.getId());
        classRecord.setCardDate(dateToString(nowDate));
        //设置考勤状态0正常1迟到5缺席
        if(type!=null){
            classRecord.setType(type);
        }
        return classRecord;
    }

}
